]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
grabHelper: Ignore key focus changes when ungrabbing
authorJasper St. Pierre <jstpierre@mecheye.net>
Sat, 16 Feb 2013 18:19:44 +0000 (13:19 -0500)
committerJasper St. Pierre <jstpierre@mecheye.net>
Sat, 16 Feb 2013 18:33:45 +0000 (13:33 -0500)
Calling onUngrab() may change key focus, either directly or
indirectly (e.g. hiding the actor). Such key focus changes
would cause an extra actor to be ungrabbed, so make sure to
ignore such focus changes while we're ungrabbing.

https://bugzilla.gnome.org/show_bug.cgi?id=693975

js/ui/grabHelper.js

index e31cc2f1809aca2461c1192a12c9bbff9f83fc68..10e597999408eeaa0742923f9618042f6ac6c71e 100644 (file)
@@ -35,6 +35,7 @@ const GrabHelper = new Lang.Class({
         this._keyFocusNotifyId = 0;
         this._focusWindowChangedId = 0;
         this._ignoreRelease = false;
+        this._isUngrabbingCount = 0;
 
         this._modalCount = 0;
         this._grabFocusCount = 0;
@@ -275,6 +276,14 @@ const GrabHelper = new Lang.Class({
         if (grabStackIndex < 0)
             return;
 
+        // We may get key focus changes when calling onUngrab, which
+        // would cause an extra ungrab() on the next actor in the
+        // stack, which is wrong. Ignore key focus changes during the
+        // ungrab, and restore the saved key focus ourselves afterwards.
+        // We use a count as ungrab() may be re-entrant, as onUngrab()
+        // may ungrab additional actors.
+        this._isUngrabbingCount++;
+
         let focus = global.stage.key_focus;
         let hadFocus = focus && this._isWithinGrabbedActor(focus);
 
@@ -306,6 +315,8 @@ const GrabHelper = new Lang.Class({
             if (poppedGrab.savedFocus)
                 poppedGrab.savedFocus.grab_key_focus();
         }
+
+        this._isUngrabbingCount--;
     },
 
     _onCapturedEvent: function(actor, event) {
@@ -348,6 +359,9 @@ const GrabHelper = new Lang.Class({
     },
 
     _onKeyFocusChanged: function() {
+        if (this._isUngrabbingCount > 0)
+            return;
+
         let focus = global.stage.key_focus;
         if (!focus || !this._isWithinGrabbedActor(focus))
             this.ungrab({ isUser: true });